package com.jmda.platform.engine.form.action;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jmda.platform.commom.HttpRequestParamParser;
import com.jmda.platform.commom.LocalCacheManager;
import com.jmda.platform.commom.SpringContextUtil;
import com.jmda.platform.database.DataBaseService;
import com.jmda.platform.engine.form.component.form.FormUIComponentAbst;
import com.jmda.platform.engine.form.event.FormGridDatasFormatEvent;
import com.jmda.platform.engine.form.event.FormGridDatasRefEvent;
import com.jmda.platform.engine.mybatis.MybatisEngine;
import com.jmda.platform.plugs.workflow.WorkFlowService;
import com.jmda.platform.plugs.workflow.model.BussinessWorkFlowBean;
import com.jmda.platform.repository.ResositoryException;
import com.jmda.platform.repository.RespositoryConstant;
import com.jmda.platform.repository.application.model.ApplicationModel;
import com.jmda.platform.repository.application.service.ApplicationSevice;
import com.jmda.platform.repository.form.action.FormController;
import com.jmda.platform.repository.form.model.FormMetadataButtonModel;
import com.jmda.platform.repository.form.model.FormMetadataMapModel;
import com.jmda.platform.repository.form.model.FormMetadataModel;
import com.jmda.platform.repository.form.model.FormModel;
import com.jmda.platform.repository.form.service.FormMetadataService;
import com.jmda.platform.repository.form.service.FormService;
import freemarker.template.Template;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 表单引擎执行类
 *
 * @author Dohia
 */
@Controller
@RequestMapping("/execute/form/ext")
public class FormEngingController {
    @Resource
    DataBaseService db;
    @Resource
    FormService formService;
    @Resource(name = "freemarkerConfig")
    FreeMarkerConfigurer freeMarkerConfigurer;
    @Resource
    FormMetadataService formMetadataService;
    @Resource
    MybatisEngine mybatis;
    @Resource
    ApplicationSevice applicationSevice;

    @RequestMapping(value = "/getPage", method = {RequestMethod.POST, RequestMethod.GET})
    public String getPage(String formId, HttpServletRequest request, ModelMap map) throws ResositoryException {

        // TODO 将来执行OGNL 表达式应用
        Map<String, Object> requestParams = HttpRequestParamParser.formatParam(request);
        StringBuffer datasparams = new StringBuffer();
        String id = null;
        //将接受到的所有参数抛给页面，并将参数拼接成字符串形式
        for (Map.Entry<String, Object> entry : requestParams.entrySet()) {
            String key = entry.getKey().toString();
            String value = entry.getValue().toString();
            map.put("param_" + key, value);
            if (!key.equals("formId")) {
                datasparams.append("&").append(key).append("=").append(value);
            }
            if (!key.equals("id")) {
                id = value;
            }
        }
        String rootPath = "";
        //从xml中读取主单数据
        FormMetadataModel masterFormMetadataModel = formMetadataService.getMasterFormMetadataModel(formId);
        StringBuffer masterButtons = new StringBuffer();
        if (masterFormMetadataModel != null) {
            //从xml中读取表单数据

            FormModel formModel = formService.get(formId);
            if (formModel != null) {
                //从xml中读取模块数据
                ApplicationModel appModel = applicationSevice.get(formModel.getApplication_id());
                if (appModel != null) {
                    //得到根路径
                    rootPath = appModel.getXieyin_code();
                }
            }

            Map<String, Object> params = LocalCacheManager.getContextParams();
            params.putAll(requestParams);
            Map<String, Object> masterData = mybatis.selectOne(masterFormMetadataModel.getForm_id(), RespositoryConstant.WORKLIST_RUNTIME_QUERY_LIST_ID + "_" + masterFormMetadataModel.getId(), params);
            //如果主单存在
            if (masterData != null) {
                List<FormMetadataMapModel> formMetadataMapModelList = masterFormMetadataModel.getFormMetadataMapList();
                map.putAll(masterData);
                //List<FormMetadataMapModel> formMetadataMapModelList = masterFormMetadataModel.getFormMetadataMapList();
                if (formMetadataMapModelList != null && formMetadataMapModelList.size() > 0) {
                    for (FormMetadataMapModel formMetadataMapModel : formMetadataMapModelList) {
                        FormUIComponentAbst abs = SpringContextUtil.getBean("UI_FORM_" + formMetadataMapModel.getUi_type());
                        if (abs != null) {
                            abs.setFormMetadataMapModel(formMetadataMapModel);
                            abs.setValue(masterData.get(formMetadataMapModel.getDb_column_lable()));
                            abs.setMapParams(params);
                            if (formMetadataMapModel.getUi_type().equals("无")) {
                                map.put(formMetadataMapModel.getColumn_lable(), masterData.get(formMetadataMapModel.getDb_column_lable()));
                            } else if (abs.getHtmlDefine(formMetadataMapModel.getUi_param()) != null) {
                                map.put(formMetadataMapModel.getColumn_lable(), abs.getHtmlDefine(formMetadataMapModel.getUi_param()));
                            }
                        }
                    }
                }
            } else {
                List<FormMetadataMapModel> formMetadataMapModelList = masterFormMetadataModel.getFormMetadataMapList();
                if (formMetadataMapModelList != null && formMetadataMapModelList.size() > 0) {
                    for (FormMetadataMapModel formMetadataMapModel : formMetadataMapModelList) {
                        FormUIComponentAbst abs = SpringContextUtil.getBean("UI_FORM_" + formMetadataMapModel.getUi_type());
                        if (abs != null) {
                            abs.setFormMetadataMapModel(formMetadataMapModel);
                            abs.setValue(null);
                            abs.setFormId(formId);
                            abs.setMapParams(params);
                            if (formMetadataMapModel.getUi_type().equals("无")) {
                                map.put(formMetadataMapModel.getColumn_lable(), "");
                            } else if (abs.getHtmlDefine(formMetadataMapModel.getUi_param()) != null) {
                                map.put(formMetadataMapModel.getColumn_lable(), abs.getHtmlDefine(formMetadataMapModel.getUi_param()));
                            }
                        }
                    }
                }
            }
            List<FormMetadataButtonModel> buttonList = masterFormMetadataModel.getFormMetadataButtonList();
            if (buttonList != null && buttonList.size() > 0) {
                for (FormMetadataButtonModel formMetadataButtonModel : buttonList) {
                    masterButtons.append(formMetadataButtonModel.getMasterButtonHtml());
                }
                map.put("buttons", masterButtons.toString());
            }
        }
        FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");

        FormModel formModel = formService.get(formId);
        String basePath = request.getContextPath();
        String extMeata = formModel.getExtendJavascript() == null ? "" : formModel.getExtendJavascript().replaceAll("\\$\\{basePath\\}", basePath);
        String personContextStr = LocalCacheManager.getContextJsParams();
        map.put("extMeta", personContextStr + extMeata);
        if (formModel.getWorkflowId() != null && !"".equals(formModel.getWorkflowId())) {
            String bussinessId = (String) requestParams.get("id");
            String workflowId = formModel.getWorkflowId();
            for (WorkFlowService service : FormController.serviceLoader) {
                List<BussinessWorkFlowBean> bussinessWorkFlowBeanList = service.getBussinessWorkFlow(workflowId, bussinessId);
                Map<String, Object> workflowMap = new HashMap<>();
                workflowMap.put("bussinessWorkFlowBeanList", bussinessWorkFlowBeanList);
                workflowMap.put("workflowId", workflowId);
                try {
                    Template workflowTemplate = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_eform_workflow.ftl");
                    String workflow = FreeMarkerTemplateUtils.processTemplateIntoString(workflowTemplate, workflowMap);
                    map.put("workflow", workflow);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
        List<FormMetadataModel> gridList = formMetadataService.getSubFormMetadataList(formId);
        for (FormMetadataModel formMetadataModel : gridList) {
            try {
                Map<String, Object> gridMap = new HashMap<String, Object>();
                gridMap.put("xieyin_code", formMetadataModel.getXieyin_code());
                gridMap.put("g_title", formMetadataModel.getName());
                String datasUrl = request.getContextPath() + "/execute/form/ext/getGridJsonDatas?formId=" + formId + "&metadataId=" + formMetadataModel.getId() + datasparams;
                gridMap.put("datas_url", datasUrl);
                gridMap.put("columns", formMetadataModel.getFormMetadataMapList());
                gridMap.put("buttons", formMetadataModel.getFormMetadataButtonList());

                if (formMetadataModel.getIs_group() != null && formMetadataModel.getIs_group() == true) {
                    gridMap.put("groupHtml", "groupField:'" + formMetadataModel.getGroup_field() + "',view: groupview, groupFormatter:function(value, rows){ if (typeof (" + formMetadataModel.getXieyin_code() + "_groupFormatter) != 'undefined'){ return " + formMetadataModel.getXieyin_code() + "_groupFormatter(value, rows);}else {return value  } },");
                } else if (formMetadataModel.getIs_detail() != null && formMetadataModel.getIs_detail() == true) {
                    gridMap.put("groupHtml", "view: detailview, detailFormatter:function(rowIndex, rowData){ if (typeof (" + formMetadataModel.getXieyin_code() + "_detailFormatter) != 'undefined'){ return " + formMetadataModel.getXieyin_code() + "_detailFormatter(rowIndex, rowData);}else {return '';  } },");
                }

                Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_eform_sub_ext_easyui.ftl");
                String gridObject = FreeMarkerTemplateUtils.processTemplateIntoString(template, gridMap);
                map.put(formMetadataModel.getXieyin_code() + "_GRID", gridObject);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 扩展token标识页面
         */
/*    	String token = TokenProccessor.getInstance().makeToken();
        request.getSession().setAttribute("token",token);  //在服务器使用session保存token(令牌)
    	map.put("token", token);*/
        String ftl = formModel.getTemplete_name() != null && formModel.getTemplete_name().trim().length() > 4 ? formModel.getTemplete_name().substring(0, formModel.getTemplete_name().trim().length() - 4) : formModel.getTemplete_name();
        return "/" + rootPath + "/" + ftl;
    }

    @RequestMapping(value = "/getGridJsonDatas", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String getGridJsonDatas(String formId, String metadataId, HttpServletRequest request) {
        // TODO 将来执行OGNL 表达式应用
        Map<String, Object> requestParams = HttpRequestParamParser.formatParam(request);
        FormMetadataModel formMetadataModel;
        try {
            formMetadataModel = formMetadataService.getFormMetadataModel(formId, metadataId);
            List<Map<String, Object>> new_list = new ArrayList<Map<String, Object>>();
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> params = LocalCacheManager.getContextParams();
            params.putAll(requestParams);
            if (formMetadataModel != null) {
                List<Map<String, Object>> list = mybatis.selectList(formMetadataModel.getForm_id(), RespositoryConstant.WORKLIST_RUNTIME_QUERY_LIST_ID + "_" + formMetadataModel.getId(), params);
                if (list != null) {
                    for (Map<String, Object> map : list) {
                        List<FormMetadataMapModel> formMetadataMapModelList = formMetadataModel.getFormMetadataMapList();
                        if (formMetadataMapModelList != null) {
                            for (FormMetadataMapModel formMetadataMapModel : formMetadataMapModelList) {

                                if ("redis".equalsIgnoreCase(formMetadataMapModel.getRef_type())) {
                                    String value = (String) map.get(formMetadataMapModel.getColumn_name());
                                    String param = formMetadataMapModel.getRef_params();
                                    String type = formMetadataMapModel.getRef_type();
                                    map.put(formMetadataMapModel.getColumn_lable() + "_", LocalCacheManager.referenceData(type, value, param));
                                }
                                if ("image".equalsIgnoreCase(formMetadataMapModel.getRef_type())) {
                                    String value = (String) map.get(formMetadataMapModel.getRef_params());
                                    String param = formMetadataMapModel.getRef_params();
                                    String type = formMetadataMapModel.getRef_type();
                                    map.put(formMetadataMapModel.getColumn_lable() + "_", LocalCacheManager.referenceData(type, value, param));
                                }
                                if ("detail".equalsIgnoreCase(formMetadataMapModel.getRef_type())) {
                                    String type = formMetadataMapModel.getRef_type();
                                    String value = (String) map.get(formMetadataMapModel.getRef_params());
                                    String param = formMetadataMapModel.getRef_params();
                                    map.put(formMetadataMapModel.getColumn_lable() + "_", LocalCacheManager.referenceData(type, value, param));
                                }
                                /**
                                 * 自定义组件
                                 * 2016.06.13
                                 * 保留原有redis,image,detail设置过的数据
                                 */
                            	if(formMetadataMapModel!=null&&formMetadataMapModel.getRef_type()!=null&&!formMetadataMapModel.getRef_type().equals("")&&!"redis".equalsIgnoreCase(formMetadataMapModel.getRef_type())&&!"image".equalsIgnoreCase(formMetadataMapModel.getRef_type())&&!"detail".equalsIgnoreCase(formMetadataMapModel.getRef_type())){
                            		try {
										Class<FormGridDatasRefEvent> eventClass = (Class<FormGridDatasRefEvent>) Class.forName(formMetadataMapModel.getRef_type());
										FormGridDatasRefEvent event = SpringContextUtil.getBean(eventClass);
										if (event != null) {
											String value = (String) map.get(formMetadataMapModel.getRef_params());
		                                    String param = formMetadataMapModel.getRef_params();
											String new_value = event.returnValue(value, param);
											map.put(formMetadataMapModel.getColumn_lable() + "_",new_value);
										}
									} catch (ClassNotFoundException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
                            	}
                                map.put(formMetadataMapModel.getColumn_lable(), map.get(formMetadataMapModel.getDb_column_lable()));
                            }
                            new_list.add(map);
                        }
                    }

                }
                if (null != formMetadataModel.getFormGridDatasFormatEventFunctionName() && !"".equals(formMetadataModel.getFormGridDatasFormatEventFunctionName().trim())) {
                    try {
                        Class<FormGridDatasFormatEvent> eventClass = (Class<FormGridDatasFormatEvent>) Class.forName(formMetadataModel.getFormGridDatasFormatEventFunctionName());
                        FormGridDatasFormatEvent event = SpringContextUtil.getBean(eventClass);
                        if (event != null) {
                            List<Map<String, Object>> new_list1 = event.format(formId, new_list);
                            new_list.clear();
                            new_list.addAll(new_list1);
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                Map<String, Object> json = new HashMap<String, Object>();
                json.put("total", new_list.size());
                json.put("rows", new_list);
                return mapper.writeValueAsString(json);
            }
        } catch (ResositoryException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "[]";
    }
}
